package commRedisService

import (
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedis"
	"time"
)

type RedisOperator struct {
	EntityType string // 实体类型
}

func (e *RedisOperator) readAgileMap() (map[string]int64, error) {
	return readAllAgileMap(e.EntityType)
}

func (e *RedisOperator) readSync() (int64, error) {
	return readSyncTime(e.EntityType)
}

func (e *RedisOperator) ReadAllDataMap() (map[string]commEntity.IEntity, error) {
	return readAllDataMap(e.EntityType)
}

func (e *RedisOperator) readEntityById(id int64) commEntity.IEntity {
	maps, err := readAllDataMap(e.EntityType)
	if err != nil {
		return nil
	}
	for _, entity := range maps {
		if entity.GetBaseEntity() == nil {
			continue
		}
		if entity.GetBaseEntity().Id == id {
			return entity
		}
	}

	return nil
}

func (e *RedisOperator) findEntityList(finder func(entity commEntity.IEntity) bool) []commEntity.IEntity {
	entityList := make([]commEntity.IEntity, 0)

	maps, err := readAllDataMap(e.EntityType)
	if err != nil {
		return entityList
	}
	for _, entity := range maps {
		if finder(entity) {
			entityList = append(entityList, entity)
		}
	}

	return entityList
}

func (e *RedisOperator) findEntity(finder func(entity commEntity.IEntity) bool) commEntity.IEntity {
	maps, err := readAllDataMap(e.EntityType)
	if err != nil {
		return nil
	}
	for _, entity := range maps {
		if finder(entity) {
			return entity
		}
	}

	return nil
}

func (e *RedisOperator) readEntityMap(hKeys []string) (map[string]commEntity.IEntity, error) {
	return readHkeyDataMap(e.EntityType, hKeys)
}

func (e *RedisOperator) readEntity(hKey string) (commEntity.IEntity, error) {
	hKeys := make([]string, 0)
	hKeys = append(hKeys, hKey)

	m, err := readHkeyDataMap(e.EntityType, hKeys)
	if err != nil {
		return nil, err
	}

	return m[hKey], nil
}

func (e *RedisOperator) getEntityCount(finder func(entity commEntity.IEntity) bool) (int, error) {
	maps, err := readAllDataMap(e.EntityType)
	if err != nil {
		return 0, err
	}

	count := 0
	for _, entity := range maps {
		if finder(entity) {
			count++
		}
	}

	return count, nil
}

func (e *RedisOperator) WriteEntityMap(dataMap map[string]commEntity.IEntity) error {
	// 步骤1：保存敏捷数据
	updateTime := time.Now().UnixMilli()

	agileMap := make(map[string]interface{})
	for k := range dataMap {
		agileMap[k] = updateTime
	}
	err := saveEntityMap(e.EntityType, "agile", agileMap)
	if err != nil {
		return err
	}

	// 步骤2：保存实体数据
	writeMap := make(map[string]interface{})
	// 将[string:entity]转换为[string:string]格式
	for key, entity := range dataMap {
		if entity == nil || entity.GetBaseEntity() == nil {
			panic("entity.BaseEntity不能为空：" + key)
		}

		po, err := entity.BuildToJson()
		if err != nil {
			continue
		}

		writeMap[key] = po
	}
	err = saveEntityMap(e.EntityType, "data", writeMap)
	if err != nil {
		return err
	}

	// 步骤3：将时间戳保存到redis
	_, err = saveSyncTime(e.EntityType, updateTime)
	if err != nil {
		return err
	}

	return nil
}

func (e *RedisOperator) writeEntity(entity commEntity.IEntity) error {
	dataMap := make(map[string]commEntity.IEntity)
	dataMap[entity.MakeServiceKey()] = entity
	return e.WriteEntityMap(dataMap)
}

func (e *RedisOperator) DeleteEntity(key string) error {
	prefix := RedisPrefix + ":" + e.EntityType

	if _, err := commRedis.Client.HDel(prefix+":agile", key).Result(); err != nil {
		return err
	}
	if _, err := commRedis.Client.HDel(prefix+":data", key).Result(); err != nil {
		return err
	}
	if _, err := commRedis.Client.Set(prefix+":sync", time.Now().UnixMilli(), -1).Result(); err != nil {
		return err
	}

	return nil
}
